<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>流媒体播放测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        .test-section {
            margin: 20px 0;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 8px;
        }
        .video-container {
            margin: 10px 0;
        }
        video {
            width: 100%;
            max-width: 640px;
            height: 360px;
            background: #000;
        }
        .url-input {
            width: 500px;
            padding: 8px;
            margin: 5px;
        }
        .btn {
            padding: 10px 20px;
            margin: 5px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .btn:hover {
            background: #0056b3;
        }
        .status {
            margin: 10px 0;
            padding: 10px;
            border-radius: 4px;
        }
        .status.success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        .status.error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        .status.info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }
    </style>
</head>
<body>
    <h1>流媒体播放测试工具</h1>
    
    <div class="test-section">
        <h3>使用说明</h3>
        <div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin: 10px 0;">
            <h4>播放测试步骤：</h4>
            <ol>
                <li>点击“检查系统状态”按钮，确保服务器正常运行</li>
                <li>点击“检查无人机状态”，查看是否有活跃的流</li>
                <li>如果没有流，请先在主页面添加无人机并启动拉流</li>
                <li>确认FLV地址正确，然后点击“播放FLV”</li>
                <li>如果仍然无法播放，请点击“清除缓存并刷新”</li>
            </ol>
            
            <h4>注意事项：</h4>
            <ul>
                <li>确保使用Chrome或Firefox浏览器</li>
                <li>如果主页面的“播放”按钮能正常工作，说明系统正常</li>
                <li>可以尝试直接访问：<a href="http://172.18.10.143:8002/live/DJ0001-1.flv" target="_blank">http://172.18.10.143:8002/live/DJ0001-1.flv</a></li>
                <li>备用地址：<a href="http://localhost:8002/live/DJI001.flv" target="_blank">http://localhost:8002/live/DJI001.flv</a></li>
            </ul>
        </div>
    </div>
    
    <!-- 系统状态检查 -->
    <div class="test-section">
        <h2>系统状态检查</h2>
        <button class="btn" onclick="checkSystemStatus()">检查系统状态</button>
        <button class="btn" onclick="clearCacheAndReload()">清除缓存并刷新</button>
        <div id="systemStatus" class="status" style="display: none;"></div>
    </div>
    
    <!-- HTTP-FLV 播放测试 -->
    <div class="test-section">
        <h2>HTTP-FLV 播放测试</h2>
        <input type="text" id="flvUrl" class="url-input" value="http://172.18.10.143:8002/live/DJ0001-1.flv" placeholder="输入FLV流地址">
        <br>
        <div style="margin: 10px 0;">
            <label>快速选择测试地址：</label>
            <button class="btn" onclick="setFlvUrl('http://172.18.10.143:8002/live/DJ0001-1.flv')">DJ0001-1</button>
            <button class="btn" onclick="setFlvUrl('http://172.18.10.143:8002/live/DJI001.flv')">DJI001</button>
            <button class="btn" onclick="setFlvUrl('http://localhost:8002/live/DJI001.flv')">localhost</button>
        </div>
        <button class="btn" onclick="testFlvUrl()">测试FLV地址</button>
        <button class="btn" onclick="playFlv()">播放FLV</button>
        <button class="btn" onclick="stopFlv()">停止播放</button>
        <div id="flvStatus" class="status" style="display: none;"></div>
        <div class="video-container">
            <video id="flvVideo" controls></video>
        </div>
    </div>
    
    <!-- 拉流状态检查 -->
    <div class="test-section">
        <h2>拉流状态检查</h2>
        <button class="btn" onclick="checkStreams()">检查当前流状态</button>
        <button class="btn" onclick="checkDrones()">检查无人机状态</button>
        <button class="btn" onclick="createTestStream()">创建测试流</button>
        <div id="streamsStatus" class="status" style="display: none;"></div>
    </div>

    <script src="flv.min.js?v=1.0.1"></script>
    <script>
        let flvPlayer = null;
        
        function showStatus(elementId, message, type = 'info') {
            const element = document.getElementById(elementId);
            element.className = `status ${type}`;
            element.textContent = message;
            element.style.display = 'block';
        }
        
        async function checkSystemStatus() {
            try {
                // 使用当前页面的主机地址，但端口改为3002
                const baseUrl = window.location.protocol + '//' + window.location.hostname + ':3002';
                const response = await fetch(baseUrl + '/api/health');
                const data = await response.json();
                
                let message = `系统状态: ${data.status}\n`;
                message += `数据库: ${data.services.database}\n`;
                message += `流服务器: ${data.services.streamServer}\n`;
                message += `活跃流数量: ${data.services.activeStreams}\n`;
                
                // 检查浏览器支持
                message += `\n浏览器支持:\n`;
                message += `FLV.js: ${typeof flvjs !== 'undefined' ? '✅ 已加载' : '❌ 未加载'}\n`;
                if (typeof flvjs !== 'undefined') {
                    message += `FLV支持: ${flvjs.isSupported() ? '✅ 支持' : '❌ 不支持'}\n`;
                }
                
                showStatus('systemStatus', message, data.status === 'ok' ? 'success' : 'error');
            } catch (error) {
                showStatus('systemStatus', `系统检查失败: ${error.message}`, 'error');
            }
        }
        
        // 清除缓存并刷新页面
        function clearCacheAndReload() {
            if (confirm('确定要清除浏览器缓存并刷新页面吗？')) {
                // 尝试清除缓存
                if ('caches' in window) {
                    caches.keys().then(names => {
                        names.forEach(name => {
                            caches.delete(name);
                        });
                    });
                }
                
                // 强制刷新页面（绕过缓存）
                window.location.reload(true);
            }
        }

        // 页面可见性处理 - 当页面不可见时停止播放，可见时重新播放以解决延迟问题
        document.addEventListener('visibilitychange', function() {
            if (document.hidden) {
                // 页面隐藏时，停止播放
                stopFlv();
                showStatus('flvStatus', '页面隐藏，已暂停播放', 'info');
            } else {
                // 页面重新可见时，重新开始播放
                const flvUrl = document.getElementById('flvUrl').value;
                if (flvUrl) {
                    playFlv();
                    showStatus('flvStatus', '页面恢复，重新连接...', 'info');
                }
            }
        });

        async function testFlvUrl() {
            const url = document.getElementById('flvUrl').value;
            try {
                const response = await fetch(url, { method: 'HEAD' });
                if (response.ok) {
                    const contentLength = response.headers.get('content-length');
                    showStatus('flvStatus', `FLV地址可访问，状态码: ${response.status}，内容长度: ${contentLength || '未知'}`, 'success');
                } else {
                    showStatus('flvStatus', `FLV地址不可访问，状态码: ${response.status}`, 'error');
                }
            } catch (error) {
                showStatus('flvStatus', `FLV地址测试失败: ${error.message}`, 'error');
            }
        }
        

        function playFlv() {
            const url = document.getElementById('flvUrl').value;
            const video = document.getElementById('flvVideo');
            
            stopFlv(); // 先停止之前的播放
            
            // 检查是否支持FLV.js
            if (typeof flvjs !== 'undefined' && flvjs.isSupported()) {
                try {
                    console.log('创建FLV播放器，URL:', url);
                    
                    // 创建FLV播放器，使用优化的配置减少加载时间
                    flvPlayer = flvjs.createPlayer({
                        type: 'flv',
                        url: url,
                        isLive: true,              // 启用直播模式
                        enableStashBuffer: false,  // 禁用缓冲以降低延迟
                        stashInitialSize: 1,       // 最小缓冲区大小
                        // 添加以下配置以优化加载速度
                        lazyLoad: false,           // 禁用懒加载
                        autoCleanupSourceBuffer: true, // 自动清理源缓冲区
                        fixAudioTimestampGap: false, // 禁用音频时间戳修复以降低延迟
                        // 提高画面质量的配置
                        seekType: 'range',         // 使用range请求以提高稳定性
                        rangeLoadZeroStart: true,  // 从0开始加载range
                        accurateSeek: true,        // 精确seek以提高播放准确性
                        // 进一步优化画面质量
                        referer: '',               // 设置referer头
                        headers: {                 // 自定义HTTP头
                            'Accept': '*/*',
                            'Cache-Control': 'no-cache'
                        }
                    }, {
                        // 优化加载性能的配置
                        enableWorker: false,       // 禁用Worker以减少初始化时间
                        enableStashBuffer: false,
                        stashInitialSize: 1,
                        // 提高画面质量的配置
                        deferLoadAfterSourceOpen: false, // 立即加载而不是等待sourceopen事件
                        // 进一步优化配置
                        maxBufferLength: 1,        // 减少缓冲区长度以降低延迟
                        maxMaxBufferLength: 3,     // 最大缓冲区长度
                        // 解决画面闪烁的配置
                        streamingAccuracy: 'high', // 高精度流媒体播放
                        enableWorkerForMSE: false, // 禁用MSE的Worker以提高兼容性
                        // 进一步优化播放稳定性
                        maxFragLookUpTolerance: 0.1, // 减少片段查找容差
                        liveBufferLatencyChasing: true, // 实时缓冲延迟追踪
                        liveBufferLatencyMaxLatency: 1.0, // 最大实时缓冲延迟
                        liveBufferLatencyMinRemain: 0.5  // 最小实时缓冲剩余
                    });
                    
                    flvPlayer.attachMediaElement(video);
                    
                    // 添加加载进度事件
                    flvPlayer.on(flvjs.Events.STATISTICS_INFO, (statInfo) => {
                        if (statInfo && statInfo.speed) {
                            showStatus('flvStatus', 'FLV流连接成功，正在播放', 'success');
                        }
                    });
                    
                    flvPlayer.on(flvjs.Events.ERROR, function(errorType, errorDetail, errorInfo) {
                        console.error('FLV播放器错误:', errorType, errorDetail, errorInfo);
                        let errorMsg = 'FLV播放错误: ';
                        if (errorDetail) {
                            errorMsg += errorDetail;
                        } else {
                            errorMsg += errorType;
                        }
                        showStatus('flvStatus', errorMsg, 'error');
                    });
                    
                    flvPlayer.on(flvjs.Events.LOADING_COMPLETE, function() {
                        console.log('FLV加载完成');
                        showStatus('flvStatus', 'FLV流加载完成', 'success');
                    });
                    
                    flvPlayer.on(flvjs.Events.METADATA_ARRIVED, function(metadata) {
                        console.log('FLV元数据:', metadata);
                        showStatus('flvStatus', 'FLV流连接成功，正在播放', 'success');
                    });
                    
                    flvPlayer.load();

                    console.log('使用FLV.js播放器播放HTTP-FLV流');
                    showStatus('flvStatus', '正在连接FLV流...', 'info');
                    
                } catch (error) {
                    console.error('FLV播放器创建失败:', error);
                    showStatus('flvStatus', `FLV播放器创建失败: ${error.message}`, 'error');
                    tryAlternativeFlvPlay(video, url);
                }
            } else {
                console.log('FLV.js库未加载或不支持');
                // 回退到直接播放（某些浏览器可能支持）
                video.src = url;
                video.play().catch(error => {
                    console.error('直接播放FLV失败:', error);
                    showStatus('flvStatus', '您的浏览器不支持FLV播放，建议使用Chrome或Firefox浏览器', 'error');
                });
            }
        }
        
        function tryAlternativeFlvPlay(video, url) {
            // 提供替代方案
            const message = `
浏览器不支持FLV直接播放。建议：
1. 使用VLC播放器打开: ${url}
2. 尝试RTMP地址: rtmp://localhost:1937/live/DJI001`;
            
            showStatus('flvStatus', message, 'error');
            
            // 显示播放器下载链接
            const container = document.getElementById('flvVideo').parentNode;
            if (!container.querySelector('.player-links')) {
                const linksDiv = document.createElement('div');
                linksDiv.className = 'player-links';
                linksDiv.innerHTML = `
                    <p style="margin: 10px 0; color: #666;">推荐播放器：</p>
                    <button onclick="copyToClipboard('${url}')" style="margin: 5px;">复制FLV地址</button>
                    <button onclick="copyToClipboard('rtmp://localhost:1937/live/DJI001')" style="margin: 5px;">复制RTMP地址</button>
                    <br><small style="color: #888;">复制地址后在VLC等播放器中打开</small>
                `;
                container.appendChild(linksDiv);
            }
        }
        
        function stopFlv() {
            const video = document.getElementById('flvVideo');
            
            // 清理之前的播放器
            if (flvPlayer) {
                flvPlayer.destroy();
                flvPlayer = null;
            }
            
            // 清理video元素
            video.pause();
            video.src = '';
            
            // 清理播放器链接
            const container = video.parentNode;
            const existingLinks = container.querySelector('.player-links');
            if (existingLinks) {
                existingLinks.remove();
            }
            
            showStatus('flvStatus', 'FLV播放已停止', 'info');
        }
        
        // 快速设置FLV地址
        function setFlvUrl(url) {
            document.getElementById('flvUrl').value = url;
            showStatus('flvStatus', `已设置播放地址: ${url}`, 'info');
        }
        

        async function checkStreams() {
            try {
                const baseUrl = window.location.protocol + '//' + window.location.hostname + ':3002';
                const response = await fetch(baseUrl + '/api/streams');
                const data = await response.json();
                
                if (data.success) {
                    const publishers = data.data.publishers || {};
                    const players = data.data.players || {};
                    
                    let message = `发布者数量: ${Object.keys(publishers).length}\n`;
                    message += `播放者数量: ${Object.keys(players).length}\n`;
                    
                    if (Object.keys(publishers).length > 0) {
                        message += `\n发布的流:\n`;
                        Object.keys(publishers).forEach(streamId => {
                            message += `- ${streamId}\n`;
                        });
                    }
                    
                    showStatus('streamsStatus', message, Object.keys(publishers).length > 0 ? 'success' : 'info');
                } else {
                    showStatus('streamsStatus', `获取流状态失败: ${data.message}`, 'error');
                }
            } catch (error) {
                showStatus('streamsStatus', `检查流状态失败: ${error.message}`, 'error');
            }
        }
        
        async function checkDrones() {
            try {
                const baseUrl = window.location.protocol + '//' + window.location.hostname + ':3002';
                const response = await fetch(baseUrl + '/api/dji/streams');
                const data = await response.json();
                
                if (data.success) {
                    const streams = data.data || [];
                    
                    let message = `无人机流数量: ${streams.length}\n`;
                    
                    if (streams.length > 0) {
                        message += `\n无人机流状态:\n`;
                        streams.forEach(stream => {
                            message += `- ${stream.id}: ${stream.status}\n`;
                        });
                    }
                    
                    showStatus('streamsStatus', message, 'success');
                } else {
                    showStatus('streamsStatus', `获取无人机状态失败: ${data.message}`, 'error');
                }
            } catch (error) {
                showStatus('streamsStatus', `检查无人机状态失败: ${error.message}`, 'error');
            }
        }
        
        // 复制到剪贴板函数
        function copyToClipboard(text) {
            if (navigator.clipboard && window.isSecureContext) {
                // 现代浏览器支持异步复制
                navigator.clipboard.writeText(text).then(() => {
                    alert('地址已复制到剪贴板: ' + text);
                }).catch(err => {
                    console.error('复制失败:', err);
                    // 回退方案
                    fallbackCopyTextToClipboard(text);
                });
            } else {
                // 旧浏览器回退方案
                fallbackCopyTextToClipboard(text);
            }
        }
        
        function fallbackCopyTextToClipboard(text) {
            const textArea = document.createElement('textarea');
            textArea.value = text;
            
            // 避免在iOS上缩放
            textArea.style.top = '0';
            textArea.style.left = '0';
            textArea.style.position = 'fixed';
            
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            
            try {
                const successful = document.execCommand('copy');
                if (successful) {
                    alert('地址已复制到剪贴板: ' + text);
                } else {
                    alert('复制失败，请手动复制: ' + text);
                }
            } catch (err) {
                console.error('复制错误:', err);
                alert('复制失败，请手动复制: ' + text);
            }
            
            document.body.removeChild(textArea);
        }
        
        // 页面加载时自动检查系统状态和FLV.js库
        window.onload = function() {
            // 设置默认FLV地址（使用用户提供的可播放地址）
            const defaultFlvUrl = 'http://172.18.10.143:8002/live/DJ0001-1.flv';
            document.getElementById('flvUrl').value = defaultFlvUrl;
            
            console.log('页面加载完成，开始检查系统状态');
            console.log('当前URL:', window.location.href);
            console.log('默认FLV地址:', defaultFlvUrl);
            
            checkSystemStatus();
            
            // 检查FLV.js是否正确加载
            setTimeout(() => {
                console.log('检查FLV.js库状态...');
                console.log('typeof flvjs:', typeof flvjs);
                
                if (typeof flvjs === 'undefined') {
                    console.error('FLV.js库未加载');
                    showStatus('flvStatus', '警告: FLV.js库未加载，FLV播放功能可能不可用', 'error');
                } else {
                    console.log('FLV.js库已加载，版本:', flvjs.version || '未知');
                    console.log('FLV.js支持状态:', flvjs.isSupported());
                    
                    if (flvjs.isSupported()) {
                        showStatus('flvStatus', '✓ FLV.js库已加载，浏览器支持FLV播放', 'success');
                    } else {
                        showStatus('flvStatus', '⚠️ FLV.js库已加载，但浏览器不支持FLV播放', 'info');
                    }
                }
            }, 1000);
        };
    </script>
</body>
</html>